package com.apache.ius.plugin;

import com.apache.api.vo.ResultEntity;
import com.apache.cache.service.CacheManager;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SystemTools;
import com.apache.exception.BusinessException;
import com.apache.tools.DataMap;
import com.apache.tools.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * description: 数据初始化缓存工具类（主要是ius服务启动后同步平台后期新增的其他表按逻辑存储的数据至缓存！）
 * 当前支持：sysAppConfig、sysZuulRoute
 * @author xhe 创建时间：2020年07月4日
 */
public class InitCacheDataUtil {
	private Logger log = LoggerFactory.getLogger(getClass());
	private static InitCacheDataUtil instance;
	private String datasource="plateform";

	public void initDataToCacheOther(String sysEname,String tableObjName){
		log.info("【开始同步其他扩展内容至缓存】--->["+sysEname+"]["+tableObjName+"]");
		 if("plateform".equals(sysEname)){
			 sysEname="";
		 }
		if("sysAppConfig".equals(tableObjName)||StrUtil.isNull(tableObjName)){
			initSysAppConfig(sysEname);
		}
		if("sysZuulRoute".equals(tableObjName)||StrUtil.isNull(tableObjName)){
			initSysZuuulRoute(sysEname);
		}
		//后期其他的在此扩展 initDataToCacheOther重写
	}

	public void initDataToCacheOther(String sysEname,String tableObjName,List<DataMap> dataList,Map<String, String> paramMap){
		log.info("【开始同步其他扩展内容至缓存】--->["+sysEname+"]["+tableObjName+"]");
		 if("sysAppConfig".equals(tableObjName)||"sysZuulRoute".equals(tableObjName)){
			 if("plateform".equals(sysEname)){
				 sysEname="";
			 }
			 if("sysAppConfig".equals(tableObjName)||StrUtil.isNull(tableObjName)){
				 initSysAppConfig(sysEname);
			 }
			 if("sysZuulRoute".equals(tableObjName)||StrUtil.isNull(tableObjName)){
				 initSysZuuulRoute(sysEname);
			 }
		 }else{
		 	initOtherData(sysEname,tableObjName,dataList,paramMap);//通用其他的
		 }
	}

	/**
	 * 系统应用配置表-缓存同步
	 */
	public void initSysAppConfig(String sysEname) {
		String searchObjName = "s_sysAppConfig";
		Map<String, Object> whereMap = new HashMap<String, Object>();
		if(!StrUtil.isNull(sysEname)){
			whereMap.put("sysAppConfig.w_sysName",sysEname);
		}
		ResultEntity resultEntity = IusPluginUtil.getInstance().select(datasource,"list",searchObjName,whereMap);
		if (resultEntity.getEntity()==null){
			return;
		}
		List<DataMap> restList = (List<DataMap>)resultEntity.getEntity();
		if(restList==null ||restList.size()==0){
			log.info("同步[高级配置]缓存：无数据可同步！");
		}
		Map<String, List<DataMap>> sysNameMap = new HashMap<>();
		for(DataMap item :restList){
			String sysnameTemp = String.valueOf(item.get("sysName"));
			List<DataMap> dataListConfig = new ArrayList<>();
			if(sysNameMap.containsKey(sysnameTemp)){
				dataListConfig=sysNameMap.get(sysnameTemp);
			}
			dataListConfig.add(item);
			sysNameMap.put(sysnameTemp,dataListConfig);
		}
		Iterator<Map.Entry<String,List<DataMap>>> iter00 = sysNameMap.entrySet().iterator();
		while (iter00.hasNext())
		{
			String sysTitle = (StrUtil.isNull(sysEname)?"所有":sysEname);
			Map.Entry<String,List<DataMap>> entry = iter00.next();
			String key_sysName = String.valueOf(entry.getKey());
			List<DataMap> dataList = (List<DataMap>)entry.getValue();
			log.info("同步[高级配置]缓存：["+sysTitle+"]待处理["+dataList.size()+"]数据start....");
			if(Validator.isEmpty(dataList) || dataList.size()==0){
				continue;
			}

			String cache_spaceName=key_sysName+"_app_config";
			SystemTools.getInstance().getCache(cache_spaceName).removeAll();

			int count = dataList.size();
			Map<String,Object> typeMap = new HashMap<>();
			for (int i = 0; i < dataList.size(); i++) {
				Map oldMap = new HashMap();
				Map obj = (Map) dataList.get(i);
				String typeCode = String.valueOf(obj.get("typeCode"));
				String appKey = String.valueOf(obj.get("appKey"));
				if(typeMap.containsKey(typeCode)){
					oldMap = (Map)typeMap.get(typeCode);
				}
				oldMap.put(appKey,obj);
				typeMap.put(typeCode,oldMap);
			}
			Iterator<Map.Entry<String,Object>> iter = typeMap.entrySet().iterator();
			int i=0;
			while (iter.hasNext())
			{
				i++;
				Map.Entry<String,Object> entry22 = iter.next();
				String key = String.valueOf(entry22.getKey());
				Map value = (Map)entry22.getValue();
				log.info("-("+(i)+")["+key+"]["+value+"] ");
			}
			SystemTools.getInstance().getCache(cache_spaceName).createCacheObject("app_config", typeMap);
			log.info("同步[高级配置]缓存：["+sysTitle+"]["+i+"]类共计["+count+"]条数据到缓存["+cache_spaceName+"]完成！");
		}
	}
	/**
	 * zuul动态路由缓存同步
	 */
	public void initSysZuuulRoute(String sysEname){
		String cache_spaceName = "zuul.routes";
		String searchObjName = "s_sysZuulRoute";
		String sysTitle = (StrUtil.isNull(sysEname)?"所有":sysEname);
		Map<String, Object> whereMap = new HashMap<String,Object>();
		whereMap.put("sysZuulRoute.w_enabled","1");
		if(!StrUtil.isNull(sysEname)){
			whereMap.put("sysZuulRoute.w_sysName",sysEname);
		}
		ResultEntity resultEntity = IusPluginUtil.getInstance().select(datasource,"list",searchObjName,whereMap);
		if (resultEntity.getEntity()==null){
			return;
		}
		List<DataMap> dataList = (List<DataMap>)resultEntity.getEntity();
		if(dataList==null ||dataList.size()==0){
			log.info("同步[高级配置]缓存：无数据可同步！");
		}
		log.info("同步[网关路由配置]缓存：["+sysTitle+"]待处理["+dataList.size()+"]数据start....");
		int count = 0;
		if(Validator.isEmpty(dataList)){
			SystemTools.getInstance().getCache(cache_spaceName).removeAll();
		}else {
			count = dataList.size();
			SystemTools.getInstance().getCache(cache_spaceName).removeAll();//重新追加最新的
			CacheManager zuulRoutes = LoadCacheFactory.getInstance().getCacheManager(cache_spaceName);
			for (int i = 0; i < dataList.size(); i++) {
				Map map = (Map) dataList.get(i);
				String key = String.valueOf(map.get("infoId"));
				log.info("-("+(i+1)+")[网关路由配置]["+String.valueOf(map.get("serviceId"))+"->"+String.valueOf(map.get("path"))+"]到缓存");
				zuulRoutes.createCacheObject(key,map);
			}
		}
		log.info("同步[网关路由配置]缓存：["+sysTitle+"]["+count+"]条数据到缓存["+cache_spaceName+"]完成！");
	}

	public void initOtherData(String sysEname,String tableObjName,List<DataMap> dataList,Map<String, String> paramMap){
		String cache_spaceName = sysEname+"_"+tableObjName+"_cache";
		log.info("【开始同步查询对象["+tableObjName+"]的内容至缓存】--->"+cache_spaceName);
		String dataCacheKey = paramMap.containsKey("dataCacheKey")?paramMap.get("dataCacheKey"):"infoId";
		log.info("缓存数据key规则依据-->["+dataCacheKey+"]");
		String[] dataCacheKeyArr = dataCacheKey.split(",");
		String sysTitle = (StrUtil.isNull(sysEname)?"所有":sysEname);
		if(dataList==null ||dataList.size()==0){
			log.info("同步缓存：无数据可同步！");
		}
		log.info("同步缓存：待处理["+dataList.size()+"]明细数据start....");
		int count = 0,groupCount = 0;
		if(Validator.isEmpty(dataList)){
			SystemTools.getInstance().getCache(cache_spaceName).removeAll();
		}else {
			count = dataList.size();
			SystemTools.getInstance().getCache(cache_spaceName).removeAll();//重新追加最新的
			CacheManager cacheManager = LoadCacheFactory.getInstance().getCacheManager(cache_spaceName);
			Map<String,List>  cacheListMap = new HashMap<>();
			if(count>0){
				for (int i = 0; i < dataList.size(); i++) {
					Map map = (Map) dataList.get(i);

					String key = "";
					for(String k : dataCacheKeyArr){
						key+=String.valueOf(map.get(k))+"_";
					}
					if (key.length() > 1) {
						key = key.substring(0, key.length() - 1);
					}
					if(StrUtil.isNull(key)){
						log.error("请指定有效值作为key，可以用dataCacheKey传入参数明确该表内字段名称");
						throw new BusinessException("请指定有效值字段作为缓存key！");
					}
					List childList = new ArrayList();
					if(cacheListMap.containsKey(key)){
						childList = cacheListMap.get(key);
					}
					childList.add(map);
					cacheListMap.put(key,childList);
//					log.info("-("+(i+1)+")["+key+"]到缓存");
				}

				if(cacheListMap.size()>0){
					Iterator cmap = cacheListMap.keySet().iterator();
					while(cmap.hasNext()){
						String key = (String) cmap.next();
						List valueList = (List) cacheListMap.get(key);
						cacheManager.createCacheObject(key,valueList);
						log.warn("-["+key+"]缓存了["+valueList.size()+"]条数据！");
						groupCount ++;
					}
					log.info("同步缓存：["+sysTitle+"]["+groupCount+"]组数据缓存["+cache_spaceName+"]完成！");
				}
			}
		}

	}
	public static InitCacheDataUtil getInstance() {
		if (null == instance) {
			instance = new InitCacheDataUtil();
		}
		return instance;
	}

}
